From: Alex Williamson Date: Sun, 12 Aug 2007 18:19:13 +0000 (-0600) Subject: [IA64] Make MMU setting of domVTi configurable X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15011 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=d3121a2b33156a4257f2e10426ae500d225881ca;p=xen.git [IA64] Make MMU setting of domVTi configurable This patch makes MMU setting of domVTi configurable. The size of VTLB and VHPT can be set by boot option. (e.g. "vti_vtlb_size=256k vti_vhpt_size=1m") Also some cleanups. Signed-off-by: Kouya Shimura --- diff --git a/xen/arch/ia64/vmx/vmmu.c b/xen/arch/ia64/vmx/vmmu.c index 9ddbc57b08..b1eec86354 100644 --- a/xen/arch/ia64/vmx/vmmu.c +++ b/xen/arch/ia64/vmx/vmmu.c @@ -19,23 +19,48 @@ * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include #include -#include -#include -#include -#include #include +static int default_vtlb_sz = DEFAULT_VTLB_SZ; +static int default_vhpt_sz = DEFAULT_VHPT_SZ; + +static void __init parse_vtlb_size(char *s) +{ + int sz = parse_size_and_unit(s, NULL); + + if (sz > 0) { + default_vtlb_sz = fls(sz - 1); + /* minimum 256KB (since calculated tag might be broken) */ + if (default_vtlb_sz < 18) + default_vtlb_sz = 18; + } +} + +static int canonicalize_vhpt_size(int sz) +{ + /* minimum 32KB */ + if (sz < 15) + return 15; + /* maximum 8MB (since purging TR is hard coded) */ + if (sz > IA64_GRANULE_SHIFT - 1) + return IA64_GRANULE_SHIFT - 1; + return sz; +} + +static void __init parse_vhpt_size(char *s) +{ + int sz = parse_size_and_unit(s, NULL); + if (sz > 0) { + default_vhpt_sz = fls(sz - 1); + default_vhpt_sz = canonicalize_vhpt_size(default_vhpt_sz); + } +} + +custom_param("vti_vtlb_size", parse_vtlb_size); +custom_param("vti_vhpt_size", parse_vhpt_size); + /* * Get the machine page frame number in 16KB unit * Input: @@ -132,66 +157,33 @@ purge_machine_tc_by_domid(domid_t domid) static int init_domain_vhpt(struct vcpu *v) { - struct page_info *page; - void * vbase; - page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0); - if ( page == NULL ) { - printk("No enough contiguous memory for init_domain_vhpt\n"); - return -ENOMEM; - } - vbase = page_to_virt(page); - memset(vbase, 0, VCPU_VHPT_SIZE); - printk(XENLOG_DEBUG "Allocate domain vhpt at 0x%p\n", vbase); - - VHPT(v,hash) = vbase; - VHPT(v,hash_sz) = VCPU_VHPT_SIZE/2; - VHPT(v,cch_buf) = (void *)((u64)vbase + VHPT(v,hash_sz)); - VHPT(v,cch_sz) = VCPU_VHPT_SIZE - VHPT(v,hash_sz); - thash_init(&(v->arch.vhpt),VCPU_VHPT_SHIFT-1); - v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val; + int rc; - return 0; + rc = thash_alloc(&(v->arch.vhpt), default_vhpt_sz, "vhpt"); + v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val; + return rc; } static void free_domain_vhpt(struct vcpu *v) { - struct page_info *page; - - if (v->arch.vhpt.hash) { - page = virt_to_page(v->arch.vhpt.hash); - free_domheap_pages(page, VCPU_VHPT_ORDER); - v->arch.vhpt.hash = 0; - } - - return; + if (v->arch.vhpt.hash) + thash_free(&(v->arch.vhpt)); } int init_domain_tlb(struct vcpu *v) { - struct page_info *page; - void * vbase; int rc; rc = init_domain_vhpt(v); if (rc) return rc; - page = alloc_domheap_pages (NULL, VCPU_VTLB_ORDER, 0); - if ( page == NULL ) { - printk("No enough contiguous memory for init_domain_tlb\n"); + rc = thash_alloc(&(v->arch.vtlb), default_vtlb_sz, "vtlb"); + if (rc) { free_domain_vhpt(v); - return -ENOMEM; + return rc; } - vbase = page_to_virt(page); - memset(vbase, 0, VCPU_VTLB_SIZE); - printk(XENLOG_DEBUG "Allocate domain vtlb at 0x%p\n", vbase); - - VTLB(v,hash) = vbase; - VTLB(v,hash_sz) = VCPU_VTLB_SIZE/2; - VTLB(v,cch_buf) = (void *)((u64)vbase + VTLB(v,hash_sz)); - VTLB(v,cch_sz) = VCPU_VTLB_SIZE - VTLB(v,hash_sz); - thash_init(&(v->arch.vtlb),VCPU_VTLB_SHIFT-1); return 0; } @@ -199,12 +191,8 @@ int init_domain_tlb(struct vcpu *v) void free_domain_tlb(struct vcpu *v) { - struct page_info *page; - - if ( v->arch.vtlb.hash) { - page = virt_to_page(v->arch.vtlb.hash); - free_domheap_pages(page, VCPU_VTLB_ORDER); - } + if (v->arch.vtlb.hash) + thash_free(&(v->arch.vtlb)); free_domain_vhpt(v); } diff --git a/xen/arch/ia64/vmx/vmx_entry.S b/xen/arch/ia64/vmx/vmx_entry.S index ef400c4f53..afe9762192 100644 --- a/xen/arch/ia64/vmx/vmx_entry.S +++ b/xen/arch/ia64/vmx/vmx_entry.S @@ -20,21 +20,9 @@ * Kun Tian (Kevin Tian) (kevin.tian@intel.com) */ -#ifndef VCPU_TLB_SHIFT -#define VCPU_TLB_SHIFT 22 -#endif #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include #include "vmx_minstate.h" GLOBAL_ENTRY(ia64_leave_nested) @@ -719,7 +707,7 @@ GLOBAL_ENTRY(vmx_switch_rr7) movl r25=PAGE_KERNEL ;; or loc5 = r25,loc5 // construct PA | page properties - mov r23 = VCPU_VHPT_SHIFT <<2 + mov r23 = IA64_GRANULE_SHIFT <<2 ;; ptr.d in3,r23 ;; diff --git a/xen/arch/ia64/vmx/vtlb.c b/xen/arch/ia64/vmx/vtlb.c index acc01128c2..2a827ebcd6 100644 --- a/xen/arch/ia64/vmx/vtlb.c +++ b/xen/arch/ia64/vmx/vtlb.c @@ -21,18 +21,7 @@ * XiaoYan Feng (Fleming Feng) (Fleming.feng@intel.com) */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#define MAX_CCH_LENGTH 40 thash_data_t *__alloc_chain(thash_cb_t *); @@ -664,7 +653,7 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 va,int is_data) /* * Initialize internal control data before service. */ -void thash_init(thash_cb_t *hcb, u64 sz) +static void thash_init(thash_cb_t *hcb, u64 sz) { int num; thash_data_t *head; @@ -688,3 +677,43 @@ void thash_init(thash_cb_t *hcb, u64 sz) hcb->cch_free_idx = 0; hcb->cch_freelist = NULL; } + +int thash_alloc(thash_cb_t *hcb, u64 sz_log2, char *what) +{ + struct page_info *page; + void * vbase; + u64 sz = 1UL << sz_log2; + + page = alloc_domheap_pages(NULL, (sz_log2 + 1 - PAGE_SHIFT), 0); + if (page == NULL) { + printk("No enough contiguous memory(%ldKB) for init_domain_%s\n", + sz >> (10 - 1), what); + return -ENOMEM; + } + vbase = page_to_virt(page); + memset(vbase, 0, sz + sz); // hash + collisions chain + if (sz_log2 >= 20 - 1) + printk(XENLOG_DEBUG "Allocate domain %s at 0x%p(%ldMB)\n", + what, vbase, sz >> (20 - 1)); + else + printk(XENLOG_DEBUG "Allocate domain %s at 0x%p(%ldKB)\n", + what, vbase, sz >> (10 - 1)); + + hcb->hash = vbase; + hcb->hash_sz = sz; + hcb->cch_buf = (void *)((u64)vbase + hcb->hash_sz); + hcb->cch_sz = sz; + thash_init(hcb, sz_log2); + return 0; +} + +void thash_free(thash_cb_t *hcb) +{ + struct page_info *page; + + if (hcb->hash) { + page = virt_to_page(hcb->hash); + free_domheap_pages(page, hcb->pta.size + 1 - PAGE_SHIFT); + hcb->hash = 0; + } +} diff --git a/xen/include/asm-ia64/vmmu.h b/xen/include/asm-ia64/vmmu.h index a3aa847c1a..3df4258b16 100644 --- a/xen/include/asm-ia64/vmmu.h +++ b/xen/include/asm-ia64/vmmu.h @@ -24,12 +24,8 @@ #define XEN_TLBthash_H #define MAX_CCN_DEPTH (15) // collision chain depth -#define VCPU_VTLB_SHIFT (20) // 1M for VTLB -#define VCPU_VTLB_SIZE (1UL<arch.vtlb._x) #define VHPT(v,_x) (v->arch.vhpt._x) #define _PAGE_PL_PRIV (CONFIG_CPL0_EMUL << 7) @@ -207,9 +203,11 @@ typedef struct thash_cb { } thash_cb_t; /* - * Initialize internal control data before service. + * Allocate and initialize internal control data before service. */ -extern void thash_init(thash_cb_t *hcb, u64 sz); +extern int thash_alloc(thash_cb_t *hcb, u64 sz, char *what); + +extern void thash_free(thash_cb_t *hcb); /* * Insert an entry to hash table.